package org.sws.domain.strategy.repository;

import org.sws.domain.strategy.model.entity.StrategyAwardEntity;
import org.sws.domain.strategy.model.entity.StrategyEntity;
import org.sws.domain.strategy.model.entity.StrategyRuleEntity;
import org.sws.domain.strategy.model.valobj.RuleTreeVO;
import org.sws.domain.strategy.model.valobj.RuleWeightVO;
import org.sws.domain.strategy.model.valobj.StrategyAwardRuleModelVO;
import org.sws.domain.strategy.model.valobj.StrategyAwardStockKeyVO;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author joyboy
 * @description 策略服务仓储接口
 */
public interface IStrategyRepository {


    /**
     * 根据营销策略id获取对应的所有奖励配置
     *
     * @param strategyId 策略ID
     * @return 奖品配置信息
     */
    List<StrategyAwardEntity> queryStrategyAwardList(Long strategyId);

    List<StrategyAwardEntity> queryStrategyAwardListByActivityId(Long activityId);

    /**
     * 存储 随机概率范围和 奖品搜索概率表
     *
     * @param key                          缓存key
     * @param rateRange                    范围
     * @param strategyAwardSearchRateTable 奖品搜索概率map
     */
    <K, V> void storeStrategyAwardSearchRateTable(String key, Integer rateRange, Map<K, V> strategyAwardSearchRateTable);

    /* 根据随机值获取奖品id */

    Integer getStrategyAwardAssemble(String strategyId, Integer rateKey);

    /**
     * @param strategyId 抽奖策略id
     */
    int getRateRange(Long strategyId);

    int getRateRange(String key);

    StrategyEntity queryStrategyEntityByStrategyId(Long strategyId);

    /**
     * 获取策略的某个规则实体
     *
     * @param strategyId 策略id
     * @param ruleModel  规则值
     */
    StrategyRuleEntity queryStrategyRule(Long strategyId, String ruleModel);

    /**
     * 获取某个规则值
     */
    String queryStrategyRuleValue(Long strategyId, String ruleModel);

    String queryStrategyRuleValue(Long strategyId, Integer awardId, String ruleModel);

    StrategyAwardRuleModelVO queryStrategyAwardRuleModelVO(Long strategyId, Integer awardId);

    /**
     * 根据规则模型，获取规则树
     *
     * @param treeId 某策略中某一奖品的规则模型
     * @return 符合规则的规则树模型
     */
    RuleTreeVO queryRuleTreeVOByTreeId(String treeId);

    /**
     * 缓存奖品库存
     *
     * @param cacheKey   缓存key
     * @param awardCount 奖品库存
     */
    void cacheStrategyAwardCount(String cacheKey, Integer awardCount);

    /**
     * redis 奖品库存扣减
     *
     * @param key        缓存key
     * @param expireTime 过期时间
     * @return 操作结果
     */
    Boolean subtractionAwardStock(String key, Date expireTime);

    void awardStockConsumeSendQueue(StrategyAwardStockKeyVO strategyAwardStockKeyVO);

    /**
     * 获取奖品库存消费队列
     */
    StrategyAwardStockKeyVO takeQueueValue(Long strategyId, Integer awardId);

    /**
     * 更新奖品库存
     *
     * @param strategyId 策略ID
     * @param awardId    奖品ID
     */
    void updateStrategyAwardStock(Long strategyId, Integer awardId);

    /**
     * 根据策略ID+奖品ID的唯一值组合，查询奖品信息
     *
     * @param strategyId 策略ID
     * @param awardId    奖品ID
     * @return 奖品实体信息
     */
    StrategyAwardEntity queryStrategyAwardEntity(Long strategyId, Integer awardId);

    /**
     * 根据奖品策略规则模型ID列表，查询RuleValue
     *
     * @param treeIds 规则树ID集合
     * @return RuleValueMap
     */
    Map<String, Integer> queryAwardRuleLockCount(String[] treeIds);

    /**
     * 查询策略ID
     *
     * @param activityId 活动ID
     * @return 策略ID
     */
    Long queryRaffleActivityByActivityId(Long activityId);

    /**
     * 查询奖品规则权重
     *
     * @param strategyId 策略ID
     * @return 奖品规则权重
     */
    List<RuleWeightVO> queryAwardRuleWeight(Long strategyId);

    /**
     * 根据用户ID、策略ID，查询用户活动账户总使用量
     *
     * @param userId     用户ID
     * @param strategyId 策略ID
     * @return 用户活动账户总使用量
     */
    Integer queryActivityAccountTotalUseCount(String userId, Long strategyId);

    /**
     * 查询有效活动的奖品配置
     */
    List<StrategyAwardStockKeyVO> queryOpenActivityStrategyAwardList();

    <K,V> Map<K,V> getCacheMap(String key);

    /**
     * 存储抽奖策略对应的Bean算法
     *
     * @param key      策略ID
     * @param beanName 策略对象名称
     */
    void cacheAlgorithmBeanName(String key, String beanName);

    /**
     * 获取存储抽奖策略对应的Bean算法
     *
     * @param key 策略ID
     * @return 策略对象名称
     */
    String getAlgorithmBeanName(String key);
}
